const trimCss = require("./scssTree/index.js")
const vueTran = require("./getStyleFromVue")
let cssTran = require("./transform_css")
const $ = require("gogocode")
const prettier = require("prettier")
async function deal(data) {
  let res = await vueTran.getStyle(data)
  let fcss1 = trimCss.scssToCss(res.style)
  let canRemove = trimCss.canRemove.bind(null, fcss1)
  let dealedCss = await trimCss.trimScss(res.style)
  let cs = cssTran.transformCss(dealedCss)
  const ast = $(data, {
    parseOptions: {
      language: "vue"
    }
  })

  /**
   * @description: 数组subArr中的元素是不是包含在fullArr当中
   * @param fullArr
   * @param subArr
   * @return
   */
  function arrayContain(fullArr, subArr) {
    if (!fullArr.length || !subArr.length) {
      return false
    }
    return (
      subArr.filter(item => {
        return ~fullArr.findIndex(it => {
          return it == item
        })
      }).length == subArr.length
    )
  }

  /**
   * @description: 递归查找父级节点中的class
   * @param node
   * @param clsArr
   * @return
   */
  function findParentClass(node, clsArr) {
    if (!node) {
      return clsArr.length
    }
    if (!clsArr.length) {
      return clsArr.length
    }
    let arr = $(node).attr("content.attributes") || []
    if (arr.length == 0) {
      return clsArr.length
    }
    let curCls = clsArr[clsArr.length - 1]
    for (let i = 0; i < arr.length; i++) {
      let attr = arr[i]
      if (attr.key.content == "class") {
        let carr = attr.value.content.split(/\s+/)
        let isContain = arrayContain(carr, curCls.split("."))
        if (!isContain) {
          return findParentClass(node.parentRef, clsArr)
        } else {
          clsArr.pop()
          return findParentClass(node.parentRef, clsArr)
        }
      }
    }
    return findParentClass(node.parentRef, clsArr)
  }

  function getArrayLast(arr) {
    if (!arr || !arr?.length) {
      return null
    }
    return arr[arr.length - 1]
  }

  //蓝湖生成的这些样式,不要
  const lanhuFilter = [
    "flex-row",
    "justify-start",
    "justify-center",
    "justify-end",
    "justify-evenly",
    "justify-around",
    "justify-between",
    "align-start",
    "align-center",
    "align-end"
  ]
  const template = ast.find("<template></template>")
  //find+each遍历所有的标签项
  let nodes = template.find(["<$_$></$_$>", "<$_$ />"])
  nodes.each(node => {
    //如果节点含有属性,则遍历它的属性
    if (Array.isArray(node.attr("content.attributes"))) {
      node.attr("content.attributes").forEach(attr => {
        // attr.key.content+=" [opacity=\"20\"]"
        if (attr.key.content == "class") {
          let cls = attr.value.content
          let clsArr = cls.split(/\s+/)
          //过滤蓝湖多余的属性
          clsArr = clsArr.filter(item => {
            return !~lanhuFilter.findIndex(la => {
              return la == item
            })
          })
          let delArr = []
          let allCls = clsArr.reduce((preCls, curCls) => {
            //遍历所有css规则
            let dealed = false
            let res = cs.cssObj.reduce((pre, obj) => {
              let cur = obj.name
              let clsName = getArrayLast(cur.split("."))
              if (clsName != curCls) {
                return pre
              }
              let rule = obj
              let isContain = arrayContain(clsArr, cur.split("."))
              if (!isContain) {
                return pre
              }
              dealed = true
              if (rule?.empty) {
                delArr.push(clsName)
              }
              if (!rule.nest) {
                //添加前得过滤掉多余的属性
                let rp = rule.rp.filter(it => {
                  return !~clsArr.findIndex(cl => {
                    return cl == it
                  })
                })
                pre.push(clsName)
                pre = pre.concat(rp)
              } else {
                let lastIdx = findParentClass(node.value.parentRef, rule.clsArr)
                if (!lastIdx) {
                  //添加前得过滤掉多余的属性
                  let rp = rule.rp.filter(it => {
                    return !~clsArr.findIndex(cl => {
                      return cl == it
                    })
                  })
                  pre.push(clsName)
                  pre = pre.concat(rp)
                }
              }
              return pre
            }, [])
            if (!dealed) {
              preCls.push(curCls)
            } else {
              preCls = preCls.concat(res)
            }
            return preCls
          }, [])
          allCls = Array.from(new Set(allCls))
          attr.value.content = allCls.join(" ")
          //将要删除的属性放在自定义属性上
          delArr.length &&
            node.attr("content.attributes").push({
              key: {
                type: "token:attribute-key",
                content: "dels"
              },
              value: {
                type: "token:attribute-value",
                content: delArr.join(" ")
              }
            })
          // delArr.length&&node.attr('content.attributes').splice(node.attr('content.attributes').length-1,1);
        }
      })
    }
  })
  template.find(["<$_$></$_$>", "<$_$ />"]).each(node => {
    //如果节点含有属性,则遍历它的属性
    if (Array.isArray(node.attr("content.attributes"))) {
      let dels = []
      node.attr("content.attributes").forEach(attr => {
        // attr.key.content+=" [opacity=\"20\"]"
        if (attr.key.content == "dels") {
          dels = attr.value.content.split(" ")
        }
      })
      node.attr("content.attributes").forEach(attr => {
        // attr.key.content+=" [opacity=\"20\"]"
        if (attr.key.content == "class") {
          let cls = attr.value.content
          let clsArr = cls.split(/\s+/)
          let cdels = dels.filter(item => {
            return canRemove(item)
          })
          clsArr = clsArr.filter(item => {
            return !cdels.find(del => {
              return del == item
            })
          })
          attr.value.content = clsArr.join(" ")
        }
      })
      if (dels.length) {
        node.attr("content.attributes").splice(node.attr("content.attributes").length - 1, 1)
      }
    }
  })
  let vue1 = ast.generate()
  let vueObj = await vueTran.getStyle(vue1)
  let fcss = trimCss.scssToCss(vueObj.style)
  let style = await prettier.format(fcss, {
    parser: "scss"
  })
  let result = `${vueObj.vue}\n${vueObj.s1}\n${style}\n${vueObj.s2}`
  return result
}

module.exports.deal = deal
